package com.ywl.study.seata;

import com.ywl.study.seata.service.AccountService;
import com.ywl.study.seata.service.OrderService;
import com.ywl.study.seata.service.StorageService;
import com.ywl.study.seata.service.impl.AccountServiceImpl;
import com.ywl.study.seata.service.impl.OrderServiceImpl;
import com.ywl.study.seata.service.impl.StorageServiceImpl;
import io.seata.rm.RMClient;
import io.seata.tm.TMClient;
import io.seata.tm.api.GlobalTransaction;
import io.seata.tm.api.GlobalTransactionContext;
import java.util.concurrent.TimeUnit;

public class Bussiness {
    public static void main(String[] args) throws Exception {
        String userId="U100001";
        String commodityCode="C00321";
        int commodityCount = 100;
        int money = 999;

        AccountService accountService = new AccountServiceImpl();
        StorageService storageService = new StorageServiceImpl();
        OrderService orderService = new OrderServiceImpl();
        orderService.setAccountService(accountService);

        accountService.reset(userId, String.valueOf(money));
        storageService.reset(commodityCode, String.valueOf(commodityCount));
        orderService.reset(null,null);

        //init seata,only once
        String applicationId="api";
        String txServiceGroup="my_test_tx_group";
        TMClient.init(applicationId,txServiceGroup);
        RMClient.init(applicationId,txServiceGroup);

        //获取全局事务
        GlobalTransaction tx=GlobalTransactionContext.getCurrentOrCreate();
        try{
           tx.begin(60000,"testBiz");
            System.out.println("begin trx,txid="+tx.getXid());
            //biz operate 3 dataSources
            //set >=5 will be rollback(200*5>999) else will be commit
            int opCount = 4;
            storageService.deduct(commodityCode, opCount);
            orderService.create(userId, commodityCode, opCount);

            //check data if negative
            boolean needCommit = ((StorageServiceImpl)storageService).validNegativeCheck("count", commodityCode)
                    && ((AccountServiceImpl)accountService).validNegativeCheck("money", userId);
            if(needCommit){
                tx.commit();
                System.out.println("xid="+tx.getXid()+" commit");
            }else{
                System.out.println("rollback trx, cause: data negative, xid is " + tx.getXid());
                tx.rollback();
            }

        }catch (Exception exx){
            System.out.println("rollback trx, cause: " + exx.getMessage() + " , xid is " + tx.getXid());
            tx.rollback();
            throw exx;
        }
        TimeUnit.SECONDS.sleep(10);

    }
}
